package main

import "fmt"

type AbstractMessage interface {
	SendMessage(text, to string)
}

type MessageImplementer interface {
	Send(text, to string)
}

type MessageSMS struct{}

func ViaSMS() MessageImplementer { // MessageSMS工厂函数
	return &MessageSMS{}
}

func (*MessageSMS) Send(text, to string) {
	fmt.Printf("send %s to %s via SMS", text, to)
}

type MessageEmail struct{}

func ViaEmail() MessageImplementer {
	return &MessageEmail{}
}

func (*MessageEmail) Send(text, to string) {
	fmt.Printf("send %s to %s via Email", text, to)
}

type CommonMessage struct {
	method MessageImplementer
}

func NewCommonMessage(method MessageImplementer) *CommonMessage {
	return &CommonMessage{
		method: method,
	}
}

func (m *CommonMessage) SendMessage(text, to string) {
	m.method.Send(text, to)
}

type UrgencyMessage struct {
	method MessageImplementer
}

func NewUrgencyMessage(method MessageImplementer) *UrgencyMessage {
	return &UrgencyMessage{
		method: method,
	}
}

func (m *UrgencyMessage) SendMessage(text, to string) {
	m.method.Send(fmt.Sprintf("[Urgency] %s", text), to)
}

func ExampleCommonSMS() {
	m := NewCommonMessage(ViaSMS())       // 创建一个ViaSMS对象，构建一个CommonMessage组合ViaSMS
	m.SendMessage("have a drink?", "bob") // 通过 CommonMessage的SendMessage方法调用ViaSMS的send方法
	fmt.Println()
	// Output:
	// send have a drink? to bob via SMS
}

func ExampleCommonEmail() {
	m := NewCommonMessage(ViaEmail())
	m.SendMessage("have a drink?", "bob")
	fmt.Println()
	// Output:
	// send have a drink? to bob via Email
}

func ExampleUrgencySMS() {
	m := NewUrgencyMessage(ViaSMS())      // 创建一个ViaSMS对象，构建一个CommonMessage组合ViaSMS
	m.SendMessage("have a drink?", "bob") // 通过 CommonMessage的SendMessage方法调用ViaSMS的send方法并对send方法参数做了处理
	fmt.Println()
	// Output:
	// send [Urgency] have a drink? to bob via SMS
}

func ExampleUrgencyEmail() {
	m := NewUrgencyMessage(ViaEmail())
	fmt.Println()
	m.SendMessage("have a drink?", "bob")
	// Output:
	// send [Urgency] have a drink? to bob via Email
}

func main() {
	ExampleCommonSMS()
	ExampleCommonEmail()
	ExampleUrgencySMS()
	ExampleUrgencyEmail()
}

/*

桥接模式

桥接（Bridge）模式的定义如下：
	将抽象与实现分离，使它们可以独立变化。它是用组合关系代替继承关系来实现，从而降低了抽象和实现这两个可变维度的耦合度。

桥接（Bridge）模式的优点是：
	由于抽象与实现分离，所以扩展能力强；
	其实现细节对客户透明。

缺点是：
	由于聚合关系建立在抽象层，要求开发者针对抽象化进行设计与编程，这增加了系统的理解与设计难度。


# 桥接模式

	桥接模式分离抽象部分和实现部分。使得两部分独立扩展。

	桥接模式类似于策略模式，区别在于策略模式封装一系列算法使得算法可以互相替换。

	策略模式使抽象部分和实现部分分离，可以独立变化。




*/
